﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Configuration;
using System.Web.Script.Serialization;

namespace analy
{
    public class AnalyAgreeMent
    {
        public  string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2") + " ";
                }
            }
            return returnStr;
        }

        public string ReadAgreeMent(byte[] res)
        {
            byte DeviceType = res[2];
            byte DeviceCmd = res[4];
            int pos = 7 + res[5] * 2;
            RetData RD = new analy.RetData();
            RD.device_type = DeviceType;
            RD.device_cmd = DeviceCmd;
            RD.device_code = res[8].ToString("00") + (res[6] * 256 + res[7]).ToString("000");
            try
            {
                switch (DeviceType)
                {
                    case 1:
                        Kzq_Read(DeviceType, DeviceCmd, res, pos, RD);
                        break;
                    case 2:
                        //DT_INIT(a_type, a_oper, bh, pos, res)
                        break;
                    case 3:
                        Kzq_init(DeviceType, DeviceCmd, res, pos, RD);
                        break;
                    case 4:
                        Bf_Read(DeviceType, DeviceCmd, res, pos, RD);
                        break;
                    case 5:
                        //DT_INIT(a_type, a_oper, bh, pos, res)
                        break;
                    case 6:
                        Bf_init(DeviceType, DeviceCmd, res, pos, RD);
                        break;
                    case 7:
                        //Wsd_Read(a_type, a_oper, bh, pos, res)
                        break;
                    case 8:
                        //DT_INIT(a_type, a_oper, bh, pos, res)
                        break;
                    case 9:
                        //WSD_init(a_type, a_oper, bh, pos, res)
                        break;
                    case 10:
                        Gprs_Read(DeviceType, DeviceCmd, res, pos, RD);
                        break;
                    default:
                        RD = new analy.RetData() { explain = "返回数据格式错误", success = 0 };
                        break;
                }
                JavaScriptSerializer JS = new JavaScriptSerializer();
                return JS.Serialize(RD);
            }
            catch
            {
                RD.success = 1;
                RD.explain = "设备正常响应,数据解析失败";
                RD.retdata = byteToHexStr(res);
                List<byte> retlist = new List<byte>();
                retlist.AddRange(res);
                JavaScriptSerializer JS = new JavaScriptSerializer();
                return JS.Serialize(RD);
            }
        }


        #region 田间控制器
        /// <summary>
        /// 控制器操作
        /// </summary>
        /// <param name="a_type">控制器类型</param>
        /// <param name="a_oper">控制器功能</param>
        /// <param name="res">得到的数据帧</param>
        /// <param name="pos">数据开始位置</param>
        /// <param name="RD">返回的数据结构体</param>
        /// <returns></returns>
        private RetData Kzq_Read(byte a_type, byte a_oper, byte[] res, int pos, RetData RD)
        {
            switch (a_oper)
            {
                case 0x31:
                    if (res[3] == 6)
                    {
                        RD.success = 0;
                        RD.explain = "阀门1开添加失败，一次任务最多2个";
                    }
                    else
                    {
                        RD.success = 1;
                        RD.explain = "阀门1开";
                    }
                    break;
                case 0x32:
                    if (res[3] == 6)
                    {
                        RD.success = 0;
                        RD.explain = "阀门1关添加失败，一次任务最多2个";
                    }
                    else
                    {
                        RD.success = 1;
                        RD.explain = "阀门1关";
                    }
                    break;
                case 0x33:
                    if (res[3] == 6)
                    {
                        RD.success = 0;
                        RD.explain = "阀门2开添加失败，一次任务最多2个";
                    }
                    else
                    {
                        RD.success = 1;
                        RD.explain = "阀门2开";
                    }
                    break;
                case 0x34:
                    if (res[3] == 6)
                    {
                        RD.success = 0;
                        RD.explain = "阀门2关添加失败，一次任务最多2个";
                    }
                    else
                    {
                        RD.success = 1;
                        RD.explain = "阀门2关";
                    }
                    break;
                case 0x35:
                    if (res[3] == 6)
                    {
                        RD.success = 0;
                        RD.explain = "阀门3开添加失败，一次任务最多2个";
                    }
                    else
                    {
                        RD.success = 1;
                        RD.explain = "阀门3开";
                    }
                    break;
                case 0x36:
                    if (res[3] == 6)
                    {
                        RD.success = 0;
                        RD.explain = "阀门3关添加失败，一次任务最多2个";
                    }
                    else
                    {
                        RD.success = 1;
                        RD.explain = "阀门3关";
                    }
                    break;
                case 0x37:
                    if (res[3] == 6)
                    {
                        RD.success = 0;
                        RD.explain = "阀门4开添加失败，一次任务最多2个";
                    }
                    else
                    {
                        RD.success = 1;
                        RD.explain = "阀门4开";
                    }
                    break;
                case 0x38:
                    if (res[3] == 6)
                    {
                        RD.success = 0;
                        RD.explain = "阀门4关添加失败，一次任务最多2个";
                    }
                    else
                    {
                        RD.success = 1;
                        RD.explain = "阀门4关";
                    }
                    break;
                case 0x39:
                    if (res[pos] <= 16)
                    {   //大口径机械阀
                        int fm1h, fm1l, fm2h, fm2l;
                        byte getres = res[pos];
                        fm1h = (getres & (128)) >> 7;
                        fm1l = (getres & (64)) >> 6;
                        fm2h = (getres & (32)) >> 5;
                        fm2l = (getres & (16)) >> 4;
                        string fm1zt = "0";
                        string fm2zt = "0";
                        string retmsg = "";
                        if (fm1h + fm1l == 0 || fm1h + fm1l == 2)//   '全开或全关表示状态不符合
                        {
                            fm1zt = "2";
                            retmsg = "阀门1状态未知,";
                        }
                        else if (fm1h == 0)//     'PD7高电平代表关
                        {
                            fm1zt = "0";
                            retmsg = "阀门1关,";
                        }
                        else if (fm1l == 0)//  'PD6高电平代表开
                        {
                            fm1zt = "1";
                            retmsg = "阀门1开,";
                        }


                        if (fm2h + fm2l == 0 || fm2h + fm2l == 2)//   '全开或全关表示状态不符合
                        {
                            fm2zt = "2";
                            retmsg += "阀门2状态未知,";
                        }
                        else if (fm2h == 0)//    'PD5高电平代表开
                        {
                            fm2zt = "1";
                            retmsg += "阀门2关,";
                        }
                        else if (fm2l == 0)//    'PD4高电平代表关
                        {
                            fm2zt = "0";
                            retmsg += "阀门2开,";
                        }
                        string[] fmzt = new string[] { fm1zt, fm2zt };
                        RD.success = 1;
                        RD.explain = retmsg;
                        RD.list = fmzt;
                    }
                    else
                    {   //田间控制器
                        string[] retzt = new string[4];
                        switch (res[pos])
                        {
                            case 97:  //a
                                retzt = new string[] { "0", "1", "1", "1" };
                                break;
                            case 98:  //b
                                retzt = new string[] { "1", "0", "1", "1" };
                                break;
                            case 99://c
                                retzt = new string[] { "1", "1", "0", "1" };
                                break;
                            case 100://d
                                retzt = new string[] { "1", "1", "1", "0" };
                                break;
                            case 101://e
                                retzt = new string[] { "0", "0", "1", "1" };
                                break;
                            case 102://f
                                retzt = new string[] { "0", "1", "0", "1" };
                                break;
                            case 103://g
                                retzt = new string[] { "0", "1", "1", "0" };
                                break;
                            case 104://h
                                retzt = new string[] { "1", "0", "0", "1" };
                                break;
                            case 105://i
                                retzt = new string[] { "1", "0", "1", "0" };
                                break;
                            case 106://j
                                retzt = new string[] { "1", "1", "0", "0" };
                                break;
                            case 107://k
                                retzt = new string[] { "0", "0", "0", "1" };
                                break;
                            case 108://l
                                retzt = new string[] { "1", "0", "0", "0" };
                                break;
                            case 109://m
                                retzt = new string[] { "0", "0", "1", "0" };
                                break;
                            case 110://n
                                retzt = new string[] { "0", "1", "0", "0" };
                                break;
                            case 111://o
                                retzt = new string[] { "0", "0", "0", "0" };
                                break;
                            case 112://p
                                retzt = new string[] { "1", "1", "1", "1" };
                                break;
                        }
                        string fm_zt = "";

                        //for(int i=0;i<4;i++)   //状态反转
                        //{
                        //    if (retzt[i] == "0")
                        //        retzt[i] = "1";
                        //    else
                        //        retzt[i] = "0";
                        //}

                        for (int i = 0; i < 4; i++)
                        {
                            if (retzt[i] == "0")
                                fm_zt += "阀门" + (i + 1).ToString() + "关,";
                            else
                                fm_zt += "阀门" + (i + 1).ToString() + "开,";
                        }
                        RD.success = 1;
                        RD.explain = fm_zt;
                        RD.list = retzt;
                    }
                    break;
                case 0x3a:
                    double  ReadVal =(double ) res[pos] * 256 + res[pos + 1];
                    string val = Math.Round(ReadVal / 1024 * 3.3 / 2.2 * (2.2 + 6.2) ,2, MidpointRounding.AwayFromZero) .ToString(); //小数点后两位四舍五入
                    RD.success = 1;
                    RD.explain = "电压:" + val + "v";
                    RD.retdata = val;
                    break;
                case 0x3b:
                    RD.success = 1;
                    RD.explain = "功能停用";
                    RD.retdata = "null";
                    break;
                case 0x3c:
                    RD.success = 1;
                    RD.explain = "功能停用";
                    break;
                case 0x3d:
                    RD.success = 1;
                    RD.explain = "功能停用";
                    break;
                case 0x3e:
                    double HReadVal = (double)res[pos] * 256 + res[pos + 1];
                    string Hval = Math.Round( HReadVal / 1024 * 3.3 / 12 * (12 + 62.2),2,MidpointRounding.AwayFromZero ) .ToString(); //小数点后两位四舍五入
                    RD.success = 1;
                    RD.explain = "电压: " + Hval + "v";
                    RD.retdata = Hval;
                    break;
            }
            return RD;
        }

        private RetData Kzq_init(byte a_type, byte a_oper, byte[] res, int pos, RetData RD)
        {
            switch (a_oper)
            {
                case 1:
                    RD.success = 1;
                    RD.explain = "固件版本" + res[pos].ToString() + "." + res[pos + 1].ToString() + "  编号:" + RD.device_code;
                    RD.list = new string [] { res[pos].ToString() + "." + res[pos + 1].ToString(),RD.device_code  };
                    break;

                case 2:
                    RD.success = 1;
                    RD.explain = "控制信息写入成功";
                    break;
            }
            return RD;
        }
        #endregion

        #region 泵房操作
        private RetData Bf_init(byte a_type, byte a_oper, byte[] res, int pos, RetData RD)
        {
            switch (a_oper)
            {
                case 1:
                    RD.success = 1;
                    RD.explain = "固件版本" + res[pos].ToString() + "." + res[pos + 1].ToString() + "  编号:" + RD.device_code;
                    RD.list = new string[] { res[pos].ToString() + "." + res[pos + 1].ToString(), RD.device_code };
                    break;

                case 2:
                    RD.success = 1;
                    RD.explain = "控制信息写入成功";
                    break;
            }
            return RD;
        }

        private RetData Bf_Read(byte a_type, byte a_oper, byte[] res, int pos, RetData RD)
        {
            switch (a_oper)
            {
                case 1:
                    RD.success = 1;
                    RD.explain = "通道1打开";
                    break;
                case 2:
                    RD.success = 1;
                    RD.explain = "通道1关闭";
                    break;
                case 3:
                    RD.success = 1;
                    RD.explain = "通道2打开";
                    break;
                case 4:
                    RD.success = 1;
                    RD.explain = "通道2关闭";
                    break;
                case 5:
                    RD.success = 1;
                    RD.explain = "通道3打开";
                    break;
                case 6:
                    RD.success = 1;
                    RD.explain = "通道3关闭";
                    break;
                case 7:
                    RD.success = 1;
                    RD.retdata = res[pos].ToString();
                    if (res[3] == 6)
                    {
                        switch (res[pos])
                        {
                            case 0:
                                RD.explain = "闸阀开失败";
                                break;
                            case 1:
                                RD.explain = "闸阀开成功";
                                break;
                            case 2:
                                RD.explain = "自动操作正在进行，不能操作";
                                break;
                            case 3:
                                RD.explain = "闸阀开";
                                break;
                        }
                    }
                    else
                    {
                        RD.explain = "闸阀开";
                        break;
                    }
                    break;
                case 8:
                    RD.success = 1;
                    RD.retdata = res[pos].ToString();
                    if (res[3] == 6)
                    {
                        switch (res[pos])
                        {
                            case 0:
                                RD.explain = "闸阀关失败";
                                break;
                            case 1:
                                RD.explain = "闸阀关成功";
                                break;
                            case 2:
                                RD.explain = "自动操作正在进行，不能操作";
                                break;
                            case 3:
                                RD.explain = "闸阀关";
                                break;
                        }
                    }
                    else
                    {
                        RD.explain = "闸阀关";
                        break;
                    }
                    break;
                case 9:
                    RD.success = 1;
                    RD.explain = "原井开成功";
                    break;
                case 10:
                    RD.success = 1;
                    RD.explain = "原井关成功";
                    break;
                case 11:
                    RD.success = 1;
                    RD.explain = "增压泵开成功";
                    break;
                case 12:
                    RD.success = 1;
                    RD.explain = "增压泵关成功";
                    break;
                case 13:
                    //        td1 = "通道1"0
                    //td2 = "通道2"1
                    //td3 = "原井"2
                    //td4 = "增压泵"3
                    //td5 = "闸刀"4
                    //td6 = "通道3"5
                    string retstring = res[pos + 2].ToString() + res[pos + 3].ToString() + res[pos + 4].ToString() + res[pos].ToString() +
                        res[pos + 1].ToString() + res[pos + 5].ToString();
                    string[] fmstata = new string[] { res[pos + 2].ToString(), res[pos + 3].ToString() , res[pos + 4].ToString() , res[pos].ToString(), res[pos + 1].ToString(), res[pos + 5].ToString() };
                    string retres = "原井" + FMState(res[pos + 2]) + ",增压泵" + FMState(res[pos + 3]) + ",闸刀" + FMState(res[pos + 4]) +
                        ",通道1" + FMState(res[pos + 0]) + ",通道2" + FMState(res[pos + 1]) + ",通道3" + FMState(res[pos + 5]);
                    RD.success = 1;
                    RD.explain = retres;
                    RD.list = fmstata;
                    RD.retdata = retstring;
                    break;
                case 14:
                    string yl = ((int)(res[pos] * 2.56 / 256 / 2.5 * 0.4 * 100) / 100).ToString("0.00") + "MPa";
                    RD.success = 1;
                    RD.explain = "压力:"+yl ;
                    RD.retdata = yl;
                    break;
                case 15:
                    if (res.Length < 15)
                    {
                        if (res[pos] == 1)
                        {
                            RD.success = 1;
                            RD.retdata = 0.ToString ();
                            RD.explain = "温湿度传感器校验码错误";
                        }
                        else
                        {
                            RD.success = 1;
                            RD.retdata = 1.ToString();
                            RD.explain = "温湿度传感器故障";
                        }
                    }
                    else
                    {
                        string SD = ((int)(res[pos] * 256 + res[pos + 1]) / 10).ToString();
                        string fh = "";
                        if (res[pos + 2] > 128)
                        {
                            res[pos + 2] -= 128;
                            fh = "-";
                        }
                        string WDL = ((int)(res[pos + 2] * 256 + res[pos + 3]) / 10).ToString();
                        string WD = fh + WDL;
                        RD.success = 1;
                        RD.explain = "湿度:" + SD + "%,温度:" + WD+"℃";
                        string[] reslist = new string[] { SD, WD };
                        RD.list = reslist;
                        RD.retdata = 2.ToString();
                    }
                    break;
                case 16:
                    RD.success = 1;
                    RD.explain = "时间同步";
                    break;
                case 17:   //报警信息
                    if (res.Length > 14)
                    {
                        string readerr = ReadError(res);
                        RD.success = 1;
                        RD.explain = readerr.Replace('@', ' ');
                        string[] reads = readerr.Split('@');
                        RD.list = reads;
            }
                    else
                    {
                RD.success = 1;
                RD.explain = "无报警信息";
            }
            break;
                case 18:
                    RD.success = 1;
                    RD.explain = "内存清除";
                    break;
                case 19:
                    RD.success = 1;
                    string[] config = new string[] { (res[pos] * 4).ToString(), (res[pos + 1] * 4).ToString() };
                    RD.list = config;
                    RD.explain = "写入参数 检测时间: " + (res[pos] * 4).ToString() + "秒  " + "排污时间: " + (res[pos + 1] * 4).ToString() + "秒";
                    break;
                case 20:
                    string bfid = res[pos-1].ToString("00") + (res[pos] * 256 + res[pos + 1]).ToString("000");
                    RD.retdata = bfid;
                    RD.success = 1;
                    RD.explain = "控制器编号:"+bfid ;
                    break;
                case 21:
                    string sj;
                    int Y, M, D, H, B, S;
                    Y = (res[pos] / 16) * 10 + res[pos] % 16;    //'年
                    M = (res[pos + 1] / 16) * 10 + res[pos + 1] % 16;  //' 月
                    D = (res[pos + 2] / 16) * 10 + res[pos + 2] % 16;  // '日
                    H = (res[pos + 3] / 16) * 10 + res[pos + 3] % 16;   // '时
                    B = (res[pos + 4] / 16) * 10 + res[pos + 4] % 16;   // '分
                    S = (res[pos + 5] / 16) * 10 + res[pos + 5] % 16;   // '秒
                    sj = Y.ToString("00") + " 年 " + M.ToString("00") + " 月 " + D.ToString("00") + " 日 " + H.ToString("00") + " 时 " + B.ToString("00") + " 分 " + S.ToString("00") + " 秒 ";
                    RD.success = 1;
                    RD.explain = "当前时间20" + sj;
                    RD.retdata ="20"+ Y.ToString("00")+"-"+M.ToString("00")+"-"+D.ToString("00") +" "+H.ToString("00")+":"+B.ToString("00")+":"+S.ToString("00");
                    break;
                case 22:  //测量电压，无此功能
                    break;
                case 23:   //报警自动回发
                    string readerrs = ReadError(res);
                    RD.success = 1;
                    RD.explain = readerrs.Replace('@', '&');
                    string[] read = readerrs.Split('@');
                    RD.list = read;
                    break;
                case 24:
                    string msg = "";
                    switch (res[pos])
                    {
                        case 0:
                            msg = "手动操作";
                            break;
                        case 1:
                            msg = "自动操作";
                            break;
                        case 2:
                            msg = "任务执行中";
                            break;
                        case 3:
                            msg = "排污阀开执行不成功";
                            break;
                        case 4:
                            msg = "闸阀关执行不成功";
                            break;
                        case 5:
                            msg = "闸阀开执行不成功";
                            break;
                        case 6:
                            msg = "排污阀关执行不成功";
                            break;
                        case 7:
                            msg = "自动操作完成";
                            break;
                    }
                    RD.success = 1;
                    RD.explain = msg;
                    RD.retdata = msg;
                    break;
                case 25:
                    RD.success = 1;
                    RD.explain = "终止自动操作";
                    break;
                case 26:
                    msg = "";
                    switch (res[pos])
                    {
                        case 0:
                            msg = "排污阀开失败";
                            break;
                        case 1:
                            msg = "排污阀开成功";
                            break;
                        case 2:
                            msg = "自动操作正在进行，不能操作";
                            break;
                        case 3:
                            msg = "排污阀开";
                            break;
                    }
                    RD.success = 1;
                    RD.explain = msg;
                    break;
                case 27:
                    string retmsg = "";
                    switch (res[pos])
                    {
                        case 0:
                            retmsg = "排污阀关失败";
                            break;
                        case 1:
                            retmsg = "排污阀关成功";
                            break;
                        case 2:
                            retmsg = "自动操作正在进行，不能操作";
                            break;
                        case 3:
                            retmsg = "排污阀关";
                            break;
                    }
                    RD.success = 1;
                    RD.explain = retmsg;
                    break;
                case 28:
                    string JC = (res[pos] * 4).ToString() + "秒";
                    string PW = (res[pos + 1] * 4).ToString() + "秒";
                    string[] JCSJ=new string[] { JC,PW};
                    RD.success = 1;
                    RD.explain = "检测时间:" + JC + " 排污时间" + PW; 
                    break;
            }
            return RD;
        }

        private string ReadError(byte[] err)
        {
            int s_c = 10;
            if (err[2] == 4 && err[4] == 17)
                s_c = 10;
            if (err[2] == 4 && err[4] == 23)
                s_c = 8;
            int bh_pos = 6;
            string bh = (err[bh_pos] * 256 + err[bh_pos + 1]).ToString("000");
            string errmsg = oper_info(err, s_c);
            string sj = "20" + read_times(err[s_c + 7]) + "-" + read_times(err[s_c + 8]) + "-" + read_times(err[s_c + 9]) + "  " + read_times(err[s_c + 10]) + ":" + read_times(err[s_c + 11]) + ":" + read_times(err[s_c + 12]);
            return sj + "@" + errmsg;
        }


        private string read_times(int t)
        {
            string txt = ((t / 16) * 10 + t % 16).ToString("00");
            return txt;
        }

        private string oper_info(byte[] err, int s)
        {
            string td1, td2, td3, td4, td5, td6;
            td1 = "断电";
            td2 = "来电";
            td3 = "原井关";
            td4 = "原井开";
            td5 = "增压泵关";
            td6 = "增压泵开";
            int i = 0;
            string info = "";
            if (err[s + 1] == 1)
            {
                info += td1;
                i += 1;
            }
            if (err[s + 2] == 1)
            {
                info += td2;
                i += 2;
            }
            if (err[s + 3] == 1)
            {
                info += td3;
            }
            if (err[s + 4] == 1)
            {
                info += td4;
            }
            if (err[s + 5] == 1)
            {
                info += td5;
            }
            if (err[s + 6] == 1)
            {
                info += td6;
            }

            switch (i)
            {
                case 1:
                    info = td1;
                    break;
                case 2:
                    info = td2;
                    break;
                case 3:
                    info = "数据有误";
                    break;
            }
            return info;
        }

        private string FMState(byte i)
        {
            if (i == 1)
                return "开";
            else
                return "关";
        }
        #endregion

        #region 协调器操作
        private RetData Gprs_Read(byte a_type, byte a_oper, byte[] res, int pos, RetData RD)
        {
            switch (a_oper)
            {
                case 1:   //协调器成功接收打包数据
                    RD.success = 1;
                    RD.explain = "协调器接收数据成功";
                    break;
                case 2:   //通信失败的编号打包
                    List<string> ids = new List<string>();
                    string tds = res[pos - 1].ToString("00");
                    for (int i = 0; i < res.Length - 12; i++)
                    {
                        string id = (res[pos + i] * 256 + res[pos + i + 1]).ToString("000");
                        i++;
                        ids.Add(tds + id);
                    }
                    RD.success = 1;
                    RD.explain = "失败数据打包";
                    RD.list = ids.ToArray();
                    break;
                case 3:   //这条没有
                    RD.success = 1;
                    RD.explain = "无操作";
                    break;
                case 4:
                    RD.success = 1;
                    RD.explain = "数据校验失败";
                    break;
                case 5:
                    RD.success = 1;
                    RD.explain = "数据太长";
                    break;
                case 6:
                    RD.success = 1;
                    RD.explain = "所有操作成功";
                    break;
                case 7:
                    RD.success = 1;
                    RD.explain = "协调器ID修改成功";
                    break;
                case 8:
                    RD.success = 1;
                    RD.explain = "协调器ID读取成功";
                    break;
                case 9:
                    RD.success = 1;
                    RD.explain = "协调器网络ID修改成功";
                    break;
                case 10:
                    RD.success = 1;
                    RD.explain = "协调器网络ID读取成功";
                    break;
                case 11:
                    string td = Convert.ToInt16(res[pos - 1]).ToString("00");
                    string CenterId = td + (res[pos] * 256 + res[pos + 1]).ToString("000");
                    RD.success = 0;
                    RD.explain = CenterId + "通信失败";
                    RD.retdata = CenterId;
                    break;
                case 15:
                    RD.success = 1;
                    RD.explain = "协调器任务被终止";
                    break;
            }
            return RD;
        }
        #endregion
    }
}
